package com.warrantyhotel.android.util;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.preference.PreferenceManager;
import android.util.Log;

import com.warrantyhotel.android.db.WarrantyHotelDBSchema;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.CountryTable;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.CurrencyTable;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.FindStoresTable;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.GetFreeTable;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.Inbox_Account_Upload_Transfers_Table;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.Inbox_Free_Table;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.Inbox_Information_Table;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.Inbox_RSS_Table;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.Inbox_Transactions_Table;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.Inbox_WarrantyTransfer_Table;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.Inbox_Warranty_Transfer_Inner_Table;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.LanguageTable;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.RetailStoresTable;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.StateTable;
import com.warrantyhotel.android.db.WarrantyHotelDBSchema.WarrantiesTable;
import com.warrantyhotel.android.model.AccountIdentifyObject;
import com.warrantyhotel.android.model.AccountIdentifySaveObject;
import com.warrantyhotel.android.model.BalanceObject;
import com.warrantyhotel.android.model.Keys;
import com.warrantyhotel.android.model.LoginObject;
import com.warrantyhotel.android.model.PurchaseObject;
import com.warrantyhotel.android.model.RedeemCodeObject;
import com.warrantyhotel.android.model.RssNewsNotifyObject;
import com.warrantyhotel.android.model.TransferObject;
import com.warrantyhotel.android.model.UserInfo;

public class JSONParser {

	public static final String SUCCESS = "Success";
	public static final String MESSAGE = "Message";
	public static final String COUNTRIES = "Countries";
	public static final String COUNTRYID = "CountryID";
	public static final String NAME = "Name";
	public static final String PHONE_PREFIX = "PhonePrefix";
	public static final String USEADDRESSSTATE = "UseAddressState";
	public static final String STATES = "States";
	public static final String STATEID = "StateID";
	public static final String COUNTRY_STATE_ID = "CountryID";
	public static final String STATENAME = "StateName";
	public static final String STATESHORTNAME = "StateShortName";
	public static final String LANGUAGES = "Languages";
	public static final String LANGUAGE_ID = "LanguageID";
	public static final String ENGLISH_NAME = "EnglishName";
	public static final String NATIVE_NAME = "NativeName";
	public static final String CULTURE = "Culture";
	public static final String CURRENCIES = "Currencies";
	public static final String CURRENCY_ID = "CurrencyID";
	public static final String LABEL = "Label";
	public static final String PREFIX = "Prefix";
	public static final String TOKEN = "Token";
	public static final String WARRANTIES = "Warranties";
	public static final String WARRANTY_ID = "WarrantyID";
	public static final String PRODUCT_PRICE = "ProductPrice";
	public static final String PRODUCT = "Product";
	public static final String WARRANTY_TEXT = "WarrantyText";
	public static final String AREA_LIMIT_TEXT = "AreaLimitText";
	public static final String RETAIL_NOTE = "RetailNote";
	public static final String PRODUCT_ID = "ProductID";
	public static final String RETAIL_STORE_ID = "RetailStoreID";
	public static final String RETAIL_STORE = "RetailStore";
	public static final String RETAIL = "Retail";
	public static final String RETAIL_ID = "RetailID";
	public static final String LIST_LABEL = "ListLabel";
	public static final String IMAGE_URL = "ListImage";
	public static final String SERVICE_NUMBER = "ServiceNumber";
	public static final String SERVICE_EMAIL = "ServiceEmail";
	public static final String ADDRESS_CITY = "AddressCity";
	public static final String ADDRESS_STATE_ID = "AddressStateID";
	public static final String ADDRESS_COUNTRY_ID = "AddressCountryID";
	public static final String ADDRESS_STREET = "AddressStreet";
	public static final String ADDRESS_POSTAL_CODE = "AddressPostalCode";
	public static final String ACCOUNT_UPLOAD_ID = "AccountUploadID";
	public static final String FIRST_NAME = "FirstName";
	public static final String LAST_NAME = "LastName";
	public static final String ACCOUNT = "Account";
	public static final String PRODUCT_NAME = "ProductName";
	public static final String STORE_NAME = "StoreName";
	public static final String ACCOUNT_UPLOADS = "AccountUploads";
	public static final String ACCOUNT_ID = "AccountID";
	public static final String FILE_URL = "FileUrl";
	public static final String EXPIRATION_DATE = "ExpirationDate";
	public static final String FILE_NAME = "FileName";
	public static final String THUMBNAIL_URL = "ThumbnailUrl";
	public static final String CONTENT_TYPE = "ContentType";
	public static final String COMMENTS = "Comments";
	public static final String PURCHASE_DATE = "PurchaseDate";
	public static final String ISSUED_UTC_DATE_TIME = "IssuedUtcDateTime";
	public static final String EXPIRATION_UTC_DATE_TIME = "ExpirationUtcDateTime";
	public static final String BIRTH_DATE = "Birthdate";
	public static final String GENDER = "Gender";
	public static final String PREFERRED_LANGUAGE_ID = "PreferredLanguageID";
	public static final String PHONE = "Phone";
	public static final String MOBILE_PHONE = "MobilePhone";
	public static final String MOBILE_PHONE_PREFIX = "MobilePhonePrefix";
	public static final String REMAINING_CREDITS = "RemainingCredits";
	public static final String REMAINING_UPLOADS = "RemainingUploads";
	public static final String MANUFACTURER_NAME = "ManufacturerName";
	public static final String END_DATE = "EndDate";
	public static final String DESCRIPTION = "Description";

	public static final int IS_OWN_WARRANTY = 1;
	public static final int IS_ACCOUNT_UPLOAD_WARRANTY = 0;
	public static final int INBOX_ITEM_VISIBLE = 0;
	public static final int INBOX_ITEM_INVISIBLE = 1;

	private ContentResolver resolver;
	private static SharedPreferences prefs;

	private static final String TAG = JSONParser.class.getSimpleName();

	public JSONParser(ContentResolver resolver, Context context) {
		this.resolver = resolver;
		prefs = PreferenceManager.getDefaultSharedPreferences(context);
	}

	public static void validateJSON(JSONObject obj) throws JSONException, Exception {
		Log.d(TAG, "Validating json...");
		if (!Boolean.TRUE.toString().equalsIgnoreCase(obj.getString(SUCCESS)))
			throw new Exception("Server responds an error. Error code: " + obj.getString(SUCCESS) + " message " + obj.getString(MESSAGE));
	}

	/**
	 * Return registration result
	 * 
	 * @param obj
	 * @return
	 * @throws Exception
	 */

	public boolean parseSuccessResponse(JSONObject obj) throws Exception {
		boolean result = false;
		result = (Boolean.TRUE.toString().equalsIgnoreCase(obj.getString(SUCCESS)));
		return result;
	}

	public TransferObject parseTransferResponse(JSONObject obj) throws Exception {
		boolean result = false;
		result = (Boolean.TRUE.toString().equalsIgnoreCase(obj.getString(SUCCESS)));
		TransferObject transferObject = new TransferObject();
		transferObject.setResult(result);
		transferObject.setMessage(obj.getString(MESSAGE));
		return transferObject;
	}

	/**
	 * 
	 * @param obj
	 * @return
	 * @throws Exception
	 */

	public String parseMessageResponse(JSONObject obj) throws Exception {
		return obj.getString(MESSAGE);
	}

	/**
	 * 
	 * Retrieving and caching credential , TokenId and AccountID
	 * 
	 * @param obj
	 * @param intent
	 * @return
	 * @throws Exception
	 */
	public LoginObject parseLoginResponse(JSONObject obj, Intent intent) throws Exception {
		boolean result = (Boolean.TRUE.toString().equalsIgnoreCase(obj.getString(SUCCESS)));

		// long sessionTime;

		SharedPreferences.Editor editor = prefs.edit();
		LoginObject loginObject = new LoginObject();

		String username = intent.getStringExtra(Keys._username);
		String password = intent.getStringExtra(Keys._password);
		boolean remembeMe = intent.getBooleanExtra(Keys._remembeMe, false);

		/* Save or clear credential */
		if (remembeMe) {
			editor.putString(Keys._username, username.trim());
			editor.putString(Keys._password, password.trim());
			editor.putBoolean(Keys._remembeMe, remembeMe);
		} else {
			editor.remove(Keys._username);
			editor.remove(Keys._password);
			editor.remove(Keys._remembeMe);
		}

		// caching TokenId and AccountID to shared preferences
		if (result) {
			JSONObject jObject = obj.getJSONObject(TOKEN);
			editor.putString(Keys._tokenId, jObject.getString(Keys._tokenId));
			editor.putString(Keys._accountId, jObject.getString(Keys._accountId));

			Log.i("_tokenId", jObject.getString(Keys._tokenId));
			Log.i("_accountId", jObject.getString(Keys._accountId));

			long startTime = DateUtis.parseDateToMillisecinds(jObject.getString(ISSUED_UTC_DATE_TIME));
			long expTime = DateUtis.parseDateToMillisecinds(jObject.getString(EXPIRATION_UTC_DATE_TIME));

			loginObject.setSeesionTime(expTime - startTime);
			loginObject.setFirstName(jObject.getJSONObject(ACCOUNT).isNull(FIRST_NAME) ? null : jObject.getJSONObject(ACCOUNT).getString(FIRST_NAME));
			loginObject.setLastName(jObject.getJSONObject(ACCOUNT).isNull(LAST_NAME) ? null : jObject.getJSONObject(ACCOUNT).getString(LAST_NAME));

		}
		editor.commit();

		// clear intent content
		intent.removeExtra(Keys._username);
		intent.removeExtra(Keys._password);

		loginObject.setMessage(obj.isNull(MESSAGE) ? null : obj.getString(MESSAGE));
		loginObject.setLoginSuccess(result);

		return loginObject;
	}

	public void parseCountryJSON(JSONObject obj) throws Exception {
		Log.d(TAG, "Parsing json Country ...");
		validateJSON(obj);

		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();

		ArrayList<ContentProviderOperation> deleteRemains = new ArrayList<ContentProviderOperation>();

		JSONArray jsons = obj.getJSONArray(COUNTRIES);
		JSONObject json;
		String[] remains = new String[jsons.length()];

		for (int i = 0; i < jsons.length(); i++) {
			json = jsons.getJSONObject(i);
			// accumulate countries
			insertOperations.add(ContentProviderOperation.newInsert(CountryTable.CONTENT_URI).withValue(CountryTable.COUNTRY_ID, json.getString(COUNTRYID))
					.withValue(CountryTable.NAME, json.getString(NAME)).withValue(CountryTable.NAME_HACK, json.getString(NAME))
					.withValue(CountryTable.PHONE_PREFIX, json.getString(PHONE_PREFIX))
					.withValue(CountryTable.USEADDRESSSTATE, json.getString(USEADDRESSSTATE).equalsIgnoreCase(Boolean.TRUE.toString()) ? 1 : 0).build());
			// accumulate remains rows
			remains[i] = json.getString(COUNTRYID);

		}

		// delete reamuins
		if (remains.length > 0) {
			deleteRemains.add(ContentProviderOperation.newDelete(CountryTable.CONTENT_URI)
					.withSelection(CountryTable.COUNTRY_ID + " not in (" + getPlaceHolder(remains) + ")", remains).build());

			resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, deleteRemains);
		}

		// update existing values
		resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);

	}

	public void parseStateJSON(JSONObject obj) throws Exception {
		Log.d(TAG, "Parsing json State ...");
		validateJSON(obj);

		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();

		ArrayList<ContentProviderOperation> deleteRemains = new ArrayList<ContentProviderOperation>();

		JSONArray jsons = obj.getJSONArray(STATES);
		JSONObject json;
		String[] remains = new String[jsons.length()];

		for (int i = 0; i < jsons.length(); i++) {
			json = jsons.getJSONObject(i);
			// accumulate countries
			insertOperations.add(ContentProviderOperation.newInsert(StateTable.CONTENT_URI).withValue(StateTable.STATE_ID, json.getInt(STATEID))
					.withValue(StateTable.COUNTRY_ID, json.getString(COUNTRY_STATE_ID)).withValue(StateTable.STATE_NAME, json.getString(STATENAME))
					.withValue(StateTable.STATE_NAME_HACK, json.getString(STATENAME)).withValue(StateTable.STATESHORTNAME, json.getString(STATESHORTNAME))
					.build());
			// accumulate remains rows
			remains[i] = json.getString(STATENAME);

		}

		// delete reamuins
		if (remains.length > 0) {
			deleteRemains.add(ContentProviderOperation.newDelete(StateTable.CONTENT_URI)
					.withSelection(StateTable.STATE_NAME + " not in (" + getPlaceHolder(remains) + ")", remains).build());

			resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, deleteRemains);

		}

		// update existing values
		resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);

	}

	public void parseLanguageJSON(JSONObject obj) throws Exception {
		Log.d(TAG, "Parsing json Language ...");
		validateJSON(obj);

		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();
		ArrayList<ContentProviderOperation> deleteRemains = new ArrayList<ContentProviderOperation>();

		JSONArray jsons = obj.getJSONArray(LANGUAGES);
		JSONObject json;
		String[] remains = new String[jsons.length()];

		for (int i = 0; i < jsons.length(); i++) {
			json = jsons.getJSONObject(i);
			// accumulate countries
			insertOperations.add(ContentProviderOperation.newInsert(LanguageTable.CONTENT_URI).withValue(LanguageTable.LANGUAGE_ID, json.getInt(LANGUAGE_ID))
					.withValue(LanguageTable.ENGLISH_NAME, json.getString(ENGLISH_NAME)).withValue(LanguageTable.NATIVE_NAME, json.getString(NATIVE_NAME))
					.withValue(LanguageTable.CULTURE, json.getString(CULTURE)).build());
			// accumulate remains rows
			remains[i] = json.getString(ENGLISH_NAME);

		}
		// delete reamuins
		if (remains.length > 0) {
			deleteRemains.add(ContentProviderOperation.newDelete(LanguageTable.CONTENT_URI)
					.withSelection(LanguageTable.ENGLISH_NAME + " not in (" + getPlaceHolder(remains) + ")", remains).build());
			resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, deleteRemains);

		}
		// update existing values
		resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);

	}

	public void parseCurrencyJSON(JSONObject obj) throws Exception {
		Log.d(TAG, "Parsing json Currency ...");
		validateJSON(obj);

		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();
		ArrayList<ContentProviderOperation> deleteRemains = new ArrayList<ContentProviderOperation>();

		JSONArray jsons = obj.getJSONArray(CURRENCIES);
		JSONObject json;
		String[] remains = new String[jsons.length()];

		for (int i = 0; i < jsons.length(); i++) {
			json = jsons.getJSONObject(i);
			// accumulate countries
			insertOperations.add(ContentProviderOperation.newInsert(CurrencyTable.CONTENT_URI)
					.withValue(CurrencyTable.CURRENCY_ID, json.getString(CURRENCY_ID)).withValue(CurrencyTable.LABEL, json.getString(LABEL))
					.withValue(CurrencyTable.PREFIX, json.getString(PREFIX)).build());
			// accumulate remains rows
			remains[i] = json.getString(CURRENCY_ID);

		}
		// delete reamuins
		if (remains.length > 0) {
			deleteRemains.add(ContentProviderOperation.newDelete(CurrencyTable.CONTENT_URI)
					.withSelection(CurrencyTable.CURRENCY_ID + " not in (" + getPlaceHolder(remains) + ")", remains).build());
			resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, deleteRemains);

		}
		// update existing values
		resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);

	}

	public void parseNearbyStyoresJSON(JSONObject obj, boolean clearCache) throws Exception {
		Log.d(TAG, "Parsing Nearby Stores ...");
		// validateJSON(obj);

		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();
		ArrayList<ContentProviderOperation> deleteRemains = new ArrayList<ContentProviderOperation>();

		if (!obj.isNull("StoresInRange")) {
			JSONArray jsons = obj.getJSONArray("StoresInRange");
			JSONArray jsonsPOI = obj.getJSONArray("PointsOfInterests");
			JSONObject json;
			JSONObject jsonPOI;
			String[] remains = new String[jsons.length() + jsonsPOI.length()];

			for (int i = 0; i < jsons.length(); i++) {
				json = jsons.getJSONObject(i);
				// accumulate stores
				insertOperations.add(ContentProviderOperation.newInsert(FindStoresTable.CONTENT_URI)
						.withValue(FindStoresTable.RETAIL_ID, json.getString(RETAIL_ID))
						.withValue(FindStoresTable.RETAIL_STORE_ID, json.getString(RETAIL_STORE_ID)).withValue(FindStoresTable.NAME, json.getString("Title"))
						.withValue(FindStoresTable.PHONE, json.getString(PHONE)).withValue(FindStoresTable.PHONE_PREFIX, json.getString(PHONE_PREFIX))
						.withValue(FindStoresTable.SERVICE_EMAIL, json.getString(SERVICE_EMAIL))
						.withValue(FindStoresTable.SERVICE_NUMBER, (json.isNull(SERVICE_NUMBER)) ? null : json.getString(SERVICE_NUMBER))
						.withValue(FindStoresTable.LOCATION_LATITUDE, json.getString("LocationLatitude")).withValue(FindStoresTable.POI, 0)
						.withValue(FindStoresTable.DESCRIPTION, (json.isNull("description")) ? null : json.getString("description"))
						.withValue(FindStoresTable.INFO, (json.isNull("Info")) ? null : json.getString("Info"))
						.withValue(FindStoresTable.THUMBNAIL, json.getString("SliderImageUrl"))
						.withValue(FindStoresTable.BANNER, json.getString("BannerImageUrl"))
						.withValue(FindStoresTable.LOCATION_LONGITUDE, json.getString("LocationLongitude")).build());
				remains[i] = json.getString(RETAIL_STORE_ID);
			}

			for (int i = 0; i < jsonsPOI.length(); i++) {
				jsonPOI = jsonsPOI.getJSONObject(i);
				Log.e("ddddd ", jsonPOI.toString());
				// accumulate POI
				insertOperations.add(ContentProviderOperation
						.newInsert(FindStoresTable.CONTENT_URI)
						// TODO
						.withValue(FindStoresTable.RETAIL_ID, jsonPOI.getString(RETAIL_ID))
						.withValue(FindStoresTable.RETAIL_STORE_ID, jsonPOI.getString(RETAIL_STORE_ID))
						.withValue(FindStoresTable.NAME, jsonPOI.getString("Title")).withValue(FindStoresTable.POI, 1)
						.withValue(FindStoresTable.PHONE, jsonPOI.getString(PHONE)).withValue(FindStoresTable.PHONE_PREFIX, jsonPOI.getString(PHONE_PREFIX))
						.withValue(FindStoresTable.SERVICE_EMAIL, jsonPOI.getString(SERVICE_EMAIL))
						.withValue(FindStoresTable.SERVICE_NUMBER, (jsonPOI.isNull(SERVICE_NUMBER)) ? null : jsonPOI.getString(SERVICE_NUMBER))
						.withValue(FindStoresTable.LOCATION_LATITUDE, jsonPOI.getString("LocationLatitude"))
						.withValue(FindStoresTable.DESCRIPTION, (jsonPOI.isNull("description")) ? null : jsonPOI.getString("description"))
						.withValue(FindStoresTable.INFO, (jsonPOI.isNull("Info")) ? null : jsonPOI.getString("Info"))
						.withValue(FindStoresTable.THUMBNAIL, jsonPOI.getString("SliderImageUrl"))
						.withValue(FindStoresTable.BANNER, jsonPOI.getString("BannerImageUrl"))
						.withValue(FindStoresTable.LOCATION_LONGITUDE, jsonPOI.getString("LocationLongitude")).build());
				remains[jsons.length() + i] = jsonPOI.getString(RETAIL_STORE_ID);
			}

			// delete reamuins
			// String selection = null;
			if (clearCache) {
				if (remains.length > 0) {
					deleteRemains.add(ContentProviderOperation.newDelete(FindStoresTable.CONTENT_URI)
							.withSelection(FindStoresTable.RETAIL_STORE_ID + " not in (" + getPlaceHolder(remains) + ")", remains).build());
					// update existing values
					resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
					resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, deleteRemains);

				} else if (remains.length == 0) {
					resolver.delete(FindStoresTable.CONTENT_URI, null, null);
				}
			}

		} else if (clearCache) {
			resolver.delete(FindStoresTable.CONTENT_URI, null, null);
		}

	}

	public RedeemCodeObject parseRedeemJSON(JSONObject obj) throws Exception {

		// {"Success":true,"Message":null,"MessageCode":2048006,"Message":"Warranties claimed at no charge to you, 4 item(s) was added to your account!","Cost":0,"Balance":73}

		RedeemCodeObject rcObject = new RedeemCodeObject();
		rcObject.setSuccess(obj.getBoolean(SUCCESS));
		rcObject.setMessage(obj.getString(MESSAGE));
		rcObject.setMessageCode(obj.getInt("MessageCode"));
		rcObject.setBalance(obj.getInt("Balance"));
		rcObject.setCost(obj.getInt("Cost"));

		return rcObject;
	}

	public RedeemCodeObject parseRedeemLiteJSON(JSONObject obj) throws Exception {
		RedeemCodeObject rcObject = new RedeemCodeObject();
		rcObject.setSuccess(obj.getBoolean(SUCCESS));
		rcObject.setMessage(obj.getString(MESSAGE));
		rcObject.setMessageCode(obj.getInt("MessageCode"));
		return rcObject;
	}

	public RedeemCodeObject parseRedeemLiteClaimJSON(JSONObject obj) throws Exception {
		RedeemCodeObject rcObject = new RedeemCodeObject();
		rcObject.setSuccess(obj.getBoolean(SUCCESS));
		rcObject.setMessage(obj.getString(MESSAGE));
		rcObject.setMessageCode(obj.getInt("MessageCode"));
		rcObject.setUploadsAvailible(obj.getInt("UploadsAvailible"));
		return rcObject;
	}

	public UserInfo parseUserInfoJSON(JSONObject obj) throws Exception {
		validateJSON(obj);
		UserInfo userInfo = new UserInfo();
		JSONObject jObj = obj.getJSONObject(ACCOUNT);
		if (!jObj.isNull(FIRST_NAME))
			userInfo.setFirstName(jObj.getString(FIRST_NAME));
		if (!jObj.isNull(LAST_NAME))
			userInfo.setLastName(jObj.getString(LAST_NAME));
		if (!jObj.isNull(ADDRESS_STREET))
			userInfo.setAddressStreet(jObj.getString(ADDRESS_STREET));
		if (!jObj.isNull(ADDRESS_COUNTRY_ID))
			userInfo.setAddressCountryId(jObj.getString(ADDRESS_COUNTRY_ID));
		if (!jObj.isNull(ADDRESS_STATE_ID))
			userInfo.setAddressStateId(jObj.getString(ADDRESS_STATE_ID));
		if (!jObj.isNull(ADDRESS_POSTAL_CODE))
			userInfo.setAddressPostalCode(jObj.getString(ADDRESS_POSTAL_CODE));
		if (!jObj.isNull(ADDRESS_CITY))
			userInfo.setAddressCity(jObj.getString(ADDRESS_CITY));
		if (!jObj.isNull(BIRTH_DATE))
			userInfo.setBirthDate(DateUtis.parseDateToMillisecinds(jObj.getString(BIRTH_DATE)));

		Boolean gender = null;
		if (jObj.isNull(GENDER))
			gender = null;
		else if (Boolean.TRUE.toString().equalsIgnoreCase(jObj.getString(GENDER)))
			gender = Boolean.TRUE;
		else if (Boolean.FALSE.toString().equalsIgnoreCase(jObj.getString(GENDER)))
			gender = Boolean.FALSE;
		userInfo.setGender(gender);

		if (!jObj.isNull(PREFERRED_LANGUAGE_ID))
			userInfo.setLanguage(jObj.getString(PREFERRED_LANGUAGE_ID));

		if (!jObj.isNull(PHONE))
			userInfo.setPhone(jObj.getString(PHONE));
		if (!jObj.isNull(MOBILE_PHONE))
			userInfo.setMobile(jObj.getString(MOBILE_PHONE));

		return userInfo;
	}

	public AccountIdentifyObject[] parseAccount_IedntifyJSON(JSONObject obj) throws Exception {

		AccountIdentifyObject[] array = null;
		JSONArray jsons = obj.getJSONArray("AccountIdentitys");
		int len = jsons.length();
		JSONObject json;
		array = new AccountIdentifyObject[len];
		for (int i = 0; i < len; i++) {
			AccountIdentifyObject accIdent = new AccountIdentifyObject();
			json = jsons.getJSONObject(i);
			accIdent.setAccountID(json.getString("AccountID"));
			accIdent.setAccountIdentityID(json.getString("AccountIdentityID"));
			accIdent.setAccountIdentityTypeID(json.getString("AccountIdentityTypeID"));
			// Log.e("AccountIdentityID", json.getString("AccountIdentityID"));
			// Log.e("AccountIdentityTypeID",
			// json.getString("AccountIdentityTypeID"));
			accIdent.setValue(json.getString("Value"));
			accIdent.setContact(json.getBoolean("Contact"));
			array[i] = accIdent;
		}

		return array;

	}

	public AccountIdentifySaveObject parseAccount_IedntifySaveJSON(JSONObject obj) throws Exception {
		AccountIdentifySaveObject result = new AccountIdentifySaveObject();
		result.setSuccess(obj.getBoolean(SUCCESS));
		result.setMessage(obj.getString(MESSAGE));
		return result;

	}

	public ArrayList<PurchaseObject> parsePurchaseJSON(JSONObject obj) throws Exception {
		ArrayList<PurchaseObject> list = new ArrayList<PurchaseObject>();
		JSONArray jsons = obj.getJSONArray("Products");
		int len = jsons.length();
		JSONObject json;
		for (int i = 0; i < len; i++) {
			json = jsons.getJSONObject(i);
			PurchaseObject purchaseObject = new PurchaseObject();
			purchaseObject.setDescription(json.getString("Description"));
			purchaseObject.setInAppProductID(json.getString("InAppProductID"));
			purchaseObject.setPublishingState(json.getString("PublishingState"));
			purchaseObject.setPurchaseType(json.getString("PurchaseType"));
			purchaseObject.setTitle(json.getString("Title"));
			list.add(purchaseObject);
		}

		return list;

	}

	// AccountIdentity/Save

	// TODO
	public ArrayList<String> parseWarrantyJSON(JSONObject obj, ArrayList<String> remains) throws Exception {
		Log.d(TAG, "Parsing json Warrannty ...");
		validateJSON(obj);

		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();

		// String accountId = prefs.getString(Keys._accountId, null);

		JSONArray jsons = obj.getJSONArray(WARRANTIES);
		JSONObject json;

		for (int i = 0; i < jsons.length(); i++) {
			json = jsons.getJSONObject(i);

			JSONObject jsonProduct = json.isNull(PRODUCT) ? null : json.getJSONObject(PRODUCT);
			JSONObject jsonRetailStore = json.isNull(RETAIL_STORE) ? null : json.getJSONObject(RETAIL_STORE);
			JSONObject jsonRetail = json.isNull(RETAIL) ? null : json.getJSONObject(RETAIL);

			insertOperations.add(ContentProviderOperation.newInsert(WarrantiesTable.CONTENT_URI)
					.withValue(WarrantiesTable.WARRANTY_ID, json.getString(WARRANTY_ID)).withValue(WarrantiesTable.WARRANTY_TYPE, IS_OWN_WARRANTY)
					.withValue(WarrantiesTable.PRODUCT_ID, (jsonProduct != null) ? jsonProduct.getString(PRODUCT_ID) : null)
					.withValue(WarrantiesTable.PRODUCT_NAME, (jsonProduct != null) ? jsonProduct.getString(NAME) : null)
					.withValue(WarrantiesTable.MANUFACTURER_NAME, (jsonProduct != null) ? jsonProduct.getString(MANUFACTURER_NAME) : null)
					.withValue(WarrantiesTable.PURCHASE_DATE, DateUtis.parseDateToMillisecinds(json.getString(PURCHASE_DATE)))
					.withValue(WarrantiesTable.CREATED_DATE, DateUtis.parseDateToMillisecinds(json.getString("CreatedDate")))
					.withValue(WarrantiesTable.END_DATE, json.getString(END_DATE))
					.withValue(WarrantiesTable.RETAIL_STORE_ID, (jsonRetailStore != null) ? jsonRetailStore.getString(RETAIL_STORE_ID) : null)
					.withValue(WarrantiesTable.RETAIL_STORE_NAME, (jsonRetailStore != null) ? jsonRetailStore.getString(NAME) : null)
					.withValue(WarrantiesTable.RETAIL_NAME, (jsonRetail != null) ? jsonRetail.getString(NAME) : null)
					.withValue(WarrantiesTable.ADDRESS_CITY, (jsonRetailStore != null) ? jsonRetailStore.getString(ADDRESS_CITY) : null)
					.withValue(WarrantiesTable.ADDRESS_COUNTRY_ID, (jsonRetailStore != null) ? jsonRetailStore.getString(ADDRESS_COUNTRY_ID) : null)
					.withValue(WarrantiesTable.ADDRESS_STATE_ID, (jsonRetailStore != null) ? jsonRetailStore.getString(ADDRESS_STATE_ID) : null)
					.withValue(WarrantiesTable.ADDRESS_POSTAL_CODE, (jsonRetailStore != null) ? jsonRetailStore.getString(ADDRESS_POSTAL_CODE) : null)
					.withValue(WarrantiesTable.ADDRESS_STREET, (jsonRetailStore != null) ? jsonRetailStore.getString(ADDRESS_STREET) : "")
					.withValue(WarrantiesTable.LATITUDE, (jsonRetailStore != null) ? jsonRetailStore.getString("LocationLatitude") : null)
					.withValue(WarrantiesTable.LONGTITUDE, (jsonRetailStore != null) ? jsonRetailStore.getString("LocationLongitude") : null)
					.withValue(WarrantiesTable.SERVICE_NUMBER, (json.isNull(SERVICE_NUMBER)) ? null : json.getString(SERVICE_NUMBER))
					.withValue(WarrantiesTable.SERVICE_EMAIL, (json.isNull(SERVICE_EMAIL)) ? null : json.getString(SERVICE_EMAIL))
					.withValue(WarrantiesTable.PRODUCT_PRICE, json.getString(PRODUCT_PRICE))
					.withValue(WarrantiesTable.ACCOUNT_ID, json.getJSONObject(ACCOUNT).getString(ACCOUNT_ID))
					.withValue(WarrantiesTable.LIST_LABEL, json.getString(LIST_LABEL)).withValue(WarrantiesTable.IMAGE_URL, json.getString(IMAGE_URL))
					.withValue(WarrantiesTable.AREA_LIMIT_TEXT, (json.isNull(DESCRIPTION)) ? null : json.getString(DESCRIPTION)).build());
			// accumulate remains rows
			remains.add(json.getString(WARRANTY_ID));

		}

		// update existing values
		resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
		return remains;
	}

	public void removeWarrantyRemains(ArrayList<String> remainsArrayList) throws Exception {
		String[] remains = remainsArrayList.toArray(new String[remainsArrayList.size()]);
		if (remains.length > 0) {
			resolver.delete(WarrantiesTable.CONTENT_URI, WarrantiesTable.WARRANTY_ID + " not in " + getPlaceHolder_v2(remains) + " AND "
					+ WarrantiesTable.WARRANTY_TYPE + " = " + IS_OWN_WARRANTY, null);
		} else if (remains.length == 0) {
			resolver.delete(WarrantiesTable.CONTENT_URI, WarrantiesTable.WARRANTY_TYPE + " = " + IS_OWN_WARRANTY, null);

		}
	}

	public void parseRetailsStoresJSON(JSONObject obj) throws Exception {
		Log.d(TAG, "Parsing RetailStore  ...");
		// validateJSON(obj);
		// Log.e(" ", obj.toString());
		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();
		JSONObject json = obj.getJSONObject(RETAIL_STORE);
		if (json != null) {

			insertOperations.add(ContentProviderOperation.newInsert(RetailStoresTable.CONTENT_URI)
					.withValue(RetailStoresTable.RETAIL_ID, json.getString(RETAIL_ID))
					.withValue(RetailStoresTable.RETAIL_STORE_ID, json.getString(RETAIL_STORE_ID)).withValue(RetailStoresTable.NAME, json.getString(NAME))
					.withValue(RetailStoresTable.ADDRESS_STREET, json.getString(ADDRESS_STREET))
					.withValue(RetailStoresTable.ADDRESS_POSTAL_CODE, json.getString(ADDRESS_POSTAL_CODE))
					.withValue(RetailStoresTable.ADDRES_SCITY, json.getString(ADDRESS_CITY))
					.withValue(RetailStoresTable.PHONE_PREFIX, (json.isNull(PHONE_PREFIX)) ? null : json.getString(PHONE_PREFIX))
					.withValue(RetailStoresTable.PHONE, (json.isNull(PHONE)) ? null : json.getString(PHONE))
					.withValue(RetailStoresTable.SERVICE_NUMBER, json.getString(SERVICE_NUMBER))
					.withValue(RetailStoresTable.LATITUDE, json.getString("LocationLatitude"))
					.withValue(RetailStoresTable.LONGTITUDE, json.getString("LocationLongitude"))
					.withValue(RetailStoresTable.ADDRESS_COUNTRY_ID, json.getString("AddressCountryID"))
					.withValue(RetailStoresTable.ADDRESS_STATE_ID, json.getString("AddressStateID"))
					.withValue(RetailStoresTable.BANNER, json.getString("BannerLink"))
					.withValue(RetailStoresTable.DESCRIPTION, (json.isNull("Description")) ? null : json.getString("Description"))
					.withValue(RetailStoresTable.INFO, (json.isNull("Info")) ? null : json.getString("Info"))
					.withValue(RetailStoresTable.SERVICE_EMAIL, (json.isNull(SERVICE_EMAIL)) ? null : json.getString(SERVICE_EMAIL)).build());
			// TODO
			// update existing values
			resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
		}
	}

	public void parseUploadWaJSON(JSONObject obj) throws Exception {
		Log.d(TAG, "Parsing RetailStore Warrannty ...");
		validateJSON(obj);

		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();

		JSONArray jsons = obj.getJSONArray(ACCOUNT_UPLOADS);
		JSONObject json;
		String[] remains = new String[jsons.length()];

		for (int i = 0; i < jsons.length(); i++) {
			json = jsons.getJSONObject(i);
			// Log.e(" ", json.toString());
			insertOperations.add(ContentProviderOperation
					.newInsert(WarrantiesTable.CONTENT_URI)

					.withValue(WarrantiesTable.WARRANTY_ID, json.getString(ACCOUNT_UPLOAD_ID))
					.withValue(WarrantiesTable.WARRANTY_TYPE, IS_ACCOUNT_UPLOAD_WARRANTY)
					.withValue(WarrantiesTable.ACCOUNT_ID, json.getString(ACCOUNT_ID))
					.withValue(WarrantiesTable.FILE_URL, json.getString(FILE_URL))
					.withValue(WarrantiesTable.PRODUCT_NAME_TO_UPLOAD, (json.isNull(PRODUCT_NAME)) ? null : json.getString(PRODUCT_NAME))
					.withValue(WarrantiesTable.STORE_NAME, (json.isNull(STORE_NAME)) ? null : json.getString(STORE_NAME))
					.withValue(WarrantiesTable.LIST_LABEL, (json.isNull(PRODUCT_NAME)) ? null : json.getString(PRODUCT_NAME))
					.withValue(WarrantiesTable.PURCHASE_DATE,
							json.isNull(PURCHASE_DATE) ? null : DateUtis.parseDateToMillisecinds(json.getString(PURCHASE_DATE)))
					.withValue(WarrantiesTable.CREATED_DATE,
							json.isNull("CreatedDate") ? null : DateUtis.parseDateToMillisecinds(json.getString("CreatedDate")))
					.withValue(WarrantiesTable.EXPIRATION_DATE, json.isNull(EXPIRATION_DATE) ? null : json.getString(EXPIRATION_DATE))
					.withValue(WarrantiesTable.FILE_NAME, json.getString(FILE_NAME)).withValue(WarrantiesTable.IMAGE_URL, json.getString(THUMBNAIL_URL))
					.withValue(WarrantiesTable.CONTENT_TYPE_WARRANTY, json.getString(CONTENT_TYPE))
					.withValue(WarrantiesTable.COMMENTS, (json.isNull(COMMENTS)) ? null : json.getString(COMMENTS)).build());
			// accumulate remains rows
			remains[i] = json.getString(ACCOUNT_UPLOAD_ID);
		}
		// delete reamains
		if (remains.length > 0) {
			resolver.delete(WarrantiesTable.CONTENT_URI, WarrantiesTable.WARRANTY_ID + " not in " + getPlaceHolder_v2(remains) + " AND "
					+ WarrantiesTable.WARRANTY_TYPE + " = " + IS_ACCOUNT_UPLOAD_WARRANTY, null);
		} else if (remains.length == 0) {
			resolver.delete(WarrantiesTable.CONTENT_URI, WarrantiesTable.WARRANTY_TYPE + " = " + IS_ACCOUNT_UPLOAD_WARRANTY, null);

		}
		// update existing values
		resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
	}

	public void parseGetFreeJSON(JSONObject obj) throws Exception {
		Log.d(TAG, "Parsing Get Free ...");
		// validateJSON(obj);

		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();

		JSONArray jsons = obj.getJSONArray("Free");
		JSONObject json;
		String[] remains = new String[jsons.length()];

		for (int i = 0; i < jsons.length(); i++) {
			json = jsons.getJSONObject(i);
			insertOperations.add(ContentProviderOperation.newInsert(GetFreeTable.CONTENT_URI).withValue(GetFreeTable.GET_FREE_ID, json.getString("GetFreeID"))
					.withValue(GetFreeTable.GET_FREE_ACTION_TYPE_ID, json.getJSONObject("ActionType").getString("GetFreeActionTypeID"))
					.withValue(GetFreeTable.LABEL, json.getJSONObject("ActionType").getString("Label"))
					.withValue(GetFreeTable.CREATED_DATE, json.getString("CreatedDate")).withValue(GetFreeTable.ACTION_TITLE, json.getString("ActionTitle"))
					.withValue(GetFreeTable.ACTION_TEXT, json.getString("ActionText")).withValue(GetFreeTable.AWARD_UPLOADS, json.getInt("AwardUploads"))
					.withValue(GetFreeTable.AWARD_CREDITS, json.getInt("AwardCredits")).withValue(GetFreeTable.THUMBNAIL_LINK, json.getString("ThumbnailLink"))
					.withValue(GetFreeTable.BANNER_LINK, json.getString("BannerLink")).build());
			// accumulate remains rows
			remains[i] = json.getString("GetFreeID");
		}
		// delete reamains
		if (remains.length > 0) {

			resolver.delete(GetFreeTable.CONTENT_URI, GetFreeTable.GET_FREE_ID + " not in " + getPlaceHolder_v2(remains), null);
		}
		// update existing values
		resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
	}

	public ArrayList<RssNewsNotifyObject> parseRssNotificationJSON(JSONObject obj) throws Exception {
		JSONArray jsons;
		JSONObject json;
		ArrayList<RssNewsNotifyObject> list = new ArrayList<RssNewsNotifyObject>();

		ArrayList<String> exicted = new ArrayList<String>();
		Cursor cursor = resolver.query(Inbox_RSS_Table.CONTENT_URI, null, null, null, null);

		if (cursor != null && cursor.moveToFirst()) {
			do {
				exicted.add(cursor.getString(cursor.getColumnIndex(Inbox_RSS_Table.GUID)));
			} while (cursor.moveToNext());
		}
		cursor.close();

		if (!obj.isNull("RSSItems")) {
			jsons = obj.getJSONArray("RSSItems");
			for (int i = 0; i < jsons.length(); i++) {
				json = jsons.getJSONObject(i);
				String item = json.getString("SyndicationItemID");
				if (!exicted.contains(item)) {
					RssNewsNotifyObject rssNewsNotifyObject = new RssNewsNotifyObject();
					rssNewsNotifyObject.setGuid(json.getString("SyndicationItemID"));
					rssNewsNotifyObject.setTitle(json.getString("Title"));
					rssNewsNotifyObject.setDescription(json.getString("Content"));
					list.add(rssNewsNotifyObject);
					// remains[i] = json.getString("SyndicationItemID");
				}
			}
		}
		return list;
	}

	private int isExpired(String dateFromJson) {
		int isExpire = (System.currentTimeMillis() > DateUtis.parseDateToMillisecinds(dateFromJson)) ? INBOX_ITEM_INVISIBLE : INBOX_ITEM_VISIBLE;

		return isExpire;
	}

	private int chechInformationIsVisible(String infoID, String expires) {
		// String prevExp = null;
		int isVisible = INBOX_ITEM_VISIBLE;
		// int result;
		// Cursor cur = resolver.query(Inbox_Information_Table.CONTENT_URI, new
		// String[] { Inbox_Information_Table._ID,
		// Inbox_Information_Table.INFO_ID, Inbox_Information_Table.EXPIRES,
		// Inbox_Information_Table.ISVISIBLE }, Inbox_Information_Table.INFO_ID
		// + " =? ", new String[] { infoID }, null);
		// if (cur != null && cur.moveToFirst()) {
		// prevExp =
		// cur.getString(cur.getColumnIndex(Inbox_Information_Table.EXPIRES));
		// isVisible =
		// cur.getInt(cur.getColumnIndex(Inbox_Information_Table.ISVISIBLE));
		// }
		// cur.close();

		// if ((expires != null && !expires.equals("null")) && (prevExp != null
		// && !prevExp.equals("null")) && !expires.equals(prevExp)) {
		// isVisible = INBOX_ITEM_VISIBLE;

		isVisible = isExpired(expires);
		// }

		return isVisible;
	}

	public void parseInboxJSON(JSONObject obj) throws Exception {
		Log.d(TAG, "Parsing Inbox ...");
		// validateJSON(obj);

		// INBOX INFO
		// *************************************************************************************************************
		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();
		ArrayList<ContentProviderOperation> updateOperations = new ArrayList<ContentProviderOperation>();

		String[] remains;
		JSONArray jsons;
		JSONObject json;
		if (!obj.isNull("Information")) {
			jsons = obj.getJSONArray("Information");
			remains = new String[jsons.length()];
			insertOperations.clear();
			for (int i = 0; i < jsons.length(); i++) {
				json = jsons.getJSONObject(i);
				insertOperations.add(ContentProviderOperation.newInsert(Inbox_Information_Table.CONTENT_URI)
						.withValue(Inbox_Information_Table.INFO_ID, json.getString("InfoID")).withValue(Inbox_Information_Table.TITLE, json.getString("Title"))
						.withValue(Inbox_Information_Table.NAME_TABLE, Inbox_Information_Table.TABLE_NAME)
						.withValue(Inbox_Information_Table.EXPIRES, json.getString("Expires")).withValue(Inbox_Information_Table.ISVISIBLE, INBOX_ITEM_VISIBLE)
						.withValue(Inbox_Information_Table.TEXT, json.getString("Text")).build());

				updateOperations.add(ContentProviderOperation.newUpdate(Inbox_Information_Table.CONTENT_URI)
						.withSelection(Inbox_Information_Table.INFO_ID + "=?", new String[] { json.getString("InfoID") })
						.withValue(Inbox_Information_Table.TITLE, json.getString("Title"))
						.withValue(Inbox_Information_Table.EXPIRES, json.getString("Expires")).withValue(Inbox_Information_Table.TEXT, json.getString("Text"))
						.withValue(Inbox_Information_Table.ISVISIBLE, chechInformationIsVisible(json.getString("InfoID"), json.getString("Expires"))).build());

				// accumulate remains rows
				remains[i] = json.getString("InfoID");
			}
			// delete reamains
			if (remains.length > 0) {

				resolver.delete(Inbox_Information_Table.CONTENT_URI, Inbox_Information_Table.INFO_ID + " not in " + getPlaceHolder_v2(remains), null);
				// update existing values
				resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
				resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, updateOperations);
			} else if (remains.length == 0) {
				resolver.delete(Inbox_Information_Table.CONTENT_URI, null, null);
			}
		} else {
			resolver.delete(Inbox_Information_Table.CONTENT_URI, null, null);
		}
		// INBOX FREE
		// *************************************************************************************************************************

		// TODO

		if (!obj.isNull("Free")) {
			jsons = obj.getJSONArray("Free");
			remains = new String[jsons.length()];
			insertOperations.clear();
			updateOperations.clear();
			for (int i = 0; i < jsons.length(); i++) {
				json = jsons.getJSONObject(i);
				insertOperations.add(ContentProviderOperation.newInsert(Inbox_Free_Table.CONTENT_URI)
						.withValue(Inbox_Free_Table.GET_FREE_ID, json.getString("GetFreeID"))
						.withValue(Inbox_Free_Table.GET_FREE_ACTION_TYPE_ID, json.getJSONObject("ActionType").getString("GetFreeActionTypeID"))
						.withValue(Inbox_Free_Table.LABEL, json.getJSONObject("ActionType").getString("Label"))
						.withValue(Inbox_Free_Table.CREATED_DATE, json.getString("CreatedDate"))
						.withValue(Inbox_Free_Table.ACTION_TITLE, json.getString("ActionTitle"))
						.withValue(Inbox_Free_Table.ACTION_TEXT, json.getString("ActionText"))
						.withValue(Inbox_Free_Table.AWARD_UPLOADS, json.getInt("AwardUploads"))
						.withValue(Inbox_Free_Table.AWARD_CREDITS, json.getInt("AwardCredits"))
						.withValue(Inbox_Free_Table.THUMBNAIL_LINK, json.getString("ThumbnailLink"))
						.withValue(Inbox_Free_Table.NAME_TABLE, Inbox_Free_Table.TABLE_NAME).withValue(Inbox_Free_Table.END_DATE, json.getString(END_DATE))
						.withValue(Inbox_Free_Table.END_DATE, json.isNull(END_DATE) ? null : json.getString(END_DATE))
						.withValue(Inbox_Free_Table.ISVISIBLE, json.isNull(END_DATE) ? INBOX_ITEM_VISIBLE : isExpired(json.getString(END_DATE)))
						.withValue(Inbox_Free_Table.BANNER_LINK, json.getString("BannerLink")).build());

				updateOperations.add(ContentProviderOperation.newUpdate(Inbox_Free_Table.CONTENT_URI)
						.withSelection(Inbox_Free_Table.GET_FREE_ID + "=?", new String[] { json.getString("GetFreeID") })
						.withValue(Inbox_Free_Table.GET_FREE_ACTION_TYPE_ID, json.getJSONObject("ActionType").getString("GetFreeActionTypeID"))
						.withValue(Inbox_Free_Table.LABEL, json.getJSONObject("ActionType").getString("Label"))
						.withValue(Inbox_Free_Table.CREATED_DATE, json.getString("CreatedDate"))
						.withValue(Inbox_Free_Table.ACTION_TITLE, json.getString("ActionTitle"))
						.withValue(Inbox_Free_Table.ACTION_TEXT, json.getString("ActionText"))
						.withValue(Inbox_Free_Table.AWARD_UPLOADS, json.getInt("AwardUploads"))
						.withValue(Inbox_Free_Table.AWARD_CREDITS, json.getInt("AwardCredits"))
						.withValue(Inbox_Free_Table.THUMBNAIL_LINK, json.getString("ThumbnailLink"))
						.withValue(Inbox_Free_Table.END_DATE, json.isNull(END_DATE) ? null : json.getString(END_DATE))
						.withValue(Inbox_Free_Table.NAME_TABLE, Inbox_Free_Table.TABLE_NAME).withValue(Inbox_Free_Table.END_DATE, json.getString(END_DATE))
						// .withValue(Inbox_Free_Table.ISVISIBLE,
						// json.isNull(END_DATE) ? INBOX_ITEM_VISIBLE :
						// isExpired(json.getString(END_DATE)))
						.withValue(Inbox_Free_Table.BANNER_LINK, json.getString("BannerLink")).build());

				// accumulate remains rows
				remains[i] = json.getString("GetFreeID");
			}
			// delete reamains
			if (remains.length > 0) {

				resolver.delete(Inbox_Free_Table.CONTENT_URI, Inbox_Free_Table.GET_FREE_ID + " not in " + getPlaceHolder_v2(remains), null);
				// update existing values
				resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
				resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, updateOperations);
			} else if (remains.length == 0) {
				resolver.delete(Inbox_Free_Table.CONTENT_URI, null, null);
			}

		} else {
			resolver.delete(Inbox_Free_Table.CONTENT_URI, null, null);
		}

		// INBOX Transactions
		// *************************************************************************************************************************
		if (!obj.isNull("Transactions")) {
			jsons = obj.getJSONArray("Transactions");
			remains = new String[jsons.length()];
			insertOperations.clear();
			for (int i = 0; i < jsons.length(); i++) {
				json = jsons.getJSONObject(i);
				insertOperations.add(ContentProviderOperation.newInsert(Inbox_Transactions_Table.CONTENT_URI)
						.withValue(Inbox_Transactions_Table.GUID, json.getString("WarrantyTransactionID"))
						.withValue(Inbox_Transactions_Table.TITLE, json.getString("Title"))
						.withValue(Inbox_Transactions_Table.NAME_TABLE, Inbox_Transactions_Table.TABLE_NAME)
						.withValue(Inbox_Transactions_Table.TEASER, json.getString("Teaser")).build());

				// //// Insert Inner
				ArrayList<ContentProviderOperation> insertOperationsInner = new ArrayList<ContentProviderOperation>();
				JSONArray innerwarranty = json.getJSONArray("Warranties");
				JSONObject js;
				for (int y = 0; y < innerwarranty.length(); y++) {
					js = innerwarranty.getJSONObject(y);

					insertOperationsInner.add(ContentProviderOperation.newInsert(Inbox_Warranty_Transfer_Inner_Table.CONTENT_URI)
							.withValue(Inbox_Warranty_Transfer_Inner_Table.WARRANTY_TRANSACTION_ID, json.getString("WarrantyTransactionID"))
							.withValue(Inbox_Warranty_Transfer_Inner_Table.WARRANTY_ID, js.getString("WarrantyID"))
							.withValue(Inbox_Warranty_Transfer_Inner_Table.ITEM_NAME, js.getJSONObject("Item").getString("Name"))
							.withValue(Inbox_Warranty_Transfer_Inner_Table.STORE_NAME, js.getJSONObject("Store").getString("Name")).build());
				}
				resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperationsInner);
				// ///////////////////////////////
				// accumulate remains rows
				remains[i] = json.getString("WarrantyTransactionID");
			}
			// delete reamains
			if (remains.length > 0) {

				resolver.delete(Inbox_Transactions_Table.CONTENT_URI, Inbox_Transactions_Table.GUID + " not in " + getPlaceHolder_v2(remains), null);
				// update existing values
				resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
			} else if (remains.length == 0) {
				resolver.delete(Inbox_Transactions_Table.CONTENT_URI, null, null);
			}
		} else {
			resolver.delete(Inbox_Transactions_Table.CONTENT_URI, null, null);
		}

		// INBOX RSS
		// *************************************************************************************************************************
		if (!obj.isNull("RSSItems")) {
			jsons = obj.getJSONArray("RSSItems");
			remains = new String[jsons.length()];
			insertOperations.clear();
			for (int i = 0; i < jsons.length(); i++) {
				json = jsons.getJSONObject(i);
				insertOperations.add(ContentProviderOperation.newInsert(Inbox_RSS_Table.CONTENT_URI)
						.withValue(Inbox_RSS_Table.GUID, json.getString("SyndicationItemID")).withValue(Inbox_RSS_Table.TITLE, json.getString("Title"))
						.withValue(Inbox_RSS_Table.CONTENT, json.getString("Content")).withValue(Inbox_RSS_Table.LINK, json.getString("Link"))
						.withValue(Inbox_RSS_Table.LINK_THUMBNAIL, json.getString("ThumbnailLink"))
						.withValue(Inbox_RSS_Table.NAME_TABLE, Inbox_RSS_Table.TABLE_NAME).withValue(Inbox_RSS_Table.LINK_BANNER, json.getString("BannerLink"))
						.build());
				// accumulate remains rows
				remains[i] = json.getString("SyndicationItemID");
			}
			// delete reamains
			if (remains.length > 0) {

				resolver.delete(Inbox_RSS_Table.CONTENT_URI, Inbox_RSS_Table.GUID + " not in " + getPlaceHolder_v2(remains), null);
				// update existing values
				resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
			} else if (remains.length == 0) {
				resolver.delete(Inbox_RSS_Table.CONTENT_URI, null, null);
			}

		} else {
			resolver.delete(Inbox_RSS_Table.CONTENT_URI, null, null);
		}

		// INBOX WARRANTY_TRANSFER
		// *************************************************************************************************************************
		if (!obj.isNull("WarrantyTransfers")) {
			jsons = obj.getJSONArray("WarrantyTransfers");
			remains = new String[jsons.length()];
			insertOperations.clear();
			for (int i = 0; i < jsons.length(); i++) {
				json = jsons.getJSONObject(i);
				insertOperations.add(ContentProviderOperation.newInsert(Inbox_WarrantyTransfer_Table.CONTENT_URI)
						.withValue(Inbox_WarrantyTransfer_Table.GUID, json.getString("WarrantyID"))
						.withValue(Inbox_WarrantyTransfer_Table.TITLE, json.getString("Title"))
						.withValue(Inbox_WarrantyTransfer_Table.TEASER, json.getString("Teaser"))
						.withValue(Inbox_WarrantyTransfer_Table.STORE_NAME, json.getJSONObject("Warranty").getJSONObject("Store").getString("Name"))
						.withValue(Inbox_WarrantyTransfer_Table.ITEM_NAME, json.getJSONObject("Warranty").getJSONObject("Item").getString("Name"))
						.withValue(Inbox_WarrantyTransfer_Table.LAST_CHANGED_DATE, json.getString("LastChangedDate"))
						.withValue(Inbox_WarrantyTransfer_Table.NAME_TABLE, Inbox_WarrantyTransfer_Table.TABLE_NAME).build());
				// accumulate remains rows
				remains[i] = json.getString("WarrantyID");
			}
			// delete reamains
			if (remains.length > 0) {

				resolver.delete(Inbox_WarrantyTransfer_Table.CONTENT_URI, Inbox_WarrantyTransfer_Table.GUID + " not in " + getPlaceHolder_v2(remains), null);
				// update existing values
				resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
			} else if (remains.length == 0) {
				resolver.delete(Inbox_WarrantyTransfer_Table.CONTENT_URI, null, null);
			}

		} else {
			resolver.delete(Inbox_WarrantyTransfer_Table.CONTENT_URI, null, null);
		}

		// INBOX ACCOUNT UPLOAD
		// *************************************************************************************************************************
		if (!obj.isNull("AccountUploadTransfers")) {
			jsons = obj.getJSONArray("AccountUploadTransfers");
			remains = new String[jsons.length()];
			insertOperations.clear();
			for (int i = 0; i < jsons.length(); i++) {
				json = jsons.getJSONObject(i);
				insertOperations.add(ContentProviderOperation.newInsert(Inbox_Account_Upload_Transfers_Table.CONTENT_URI)
						.withValue(Inbox_Account_Upload_Transfers_Table.GUID, json.getString("AccountUploadID"))
						.withValue(Inbox_Account_Upload_Transfers_Table.EXPIRATION_DATE, json.getString("ExpirationDate"))
						.withValue(Inbox_Account_Upload_Transfers_Table.FILE_URL, json.getString("FileUrl"))
						.withValue(Inbox_Account_Upload_Transfers_Table.PURCHASE_DATE, json.getString("PurchaseDate"))
						.withValue(Inbox_Account_Upload_Transfers_Table.STORE_NAME, json.getString("StoreName"))
						.withValue(Inbox_Account_Upload_Transfers_Table.TEASER, json.getString("Teaser"))
						.withValue(Inbox_Account_Upload_Transfers_Table.PRODUCTNAME, json.getString("ProductName"))
						.withValue(Inbox_Account_Upload_Transfers_Table.TITLE, json.getString("Title"))
						.withValue(Inbox_Account_Upload_Transfers_Table.NAME_TABLE, Inbox_Account_Upload_Transfers_Table.TABLE_NAME).build());
				// accumulate remains rows
				remains[i] = json.getString("AccountUploadID");
			}
			// delete reamains
			if (remains.length > 0) {

				resolver.delete(Inbox_Account_Upload_Transfers_Table.CONTENT_URI, Inbox_Account_Upload_Transfers_Table.GUID + " not in "
						+ getPlaceHolder_v2(remains), null);
				// update existing values
				resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
			} else if (remains.length == 0) {
				resolver.delete(Inbox_Account_Upload_Transfers_Table.CONTENT_URI, null, null);
			}

		} else {
			resolver.delete(Inbox_Account_Upload_Transfers_Table.CONTENT_URI, null, null);
		}
	}

	public BalanceObject parseBalanceJSON(JSONObject obj) throws JSONException, Exception {
		Log.d(TAG, "Parsing Balance ...");
		validateJSON(obj);
		BalanceObject balanceObject = new BalanceObject();
		balanceObject.setRemainingCredits(obj.getString(REMAINING_CREDITS));
		balanceObject.setRemainingUploads(obj.getString(REMAINING_UPLOADS));
		return balanceObject;

	}

	public void parseUploadSingleJSON(JSONObject obj, String account_upload_id) throws Exception {
		Log.d(TAG, "Parsing Single Upload Warrannty ...");
		validateJSON(obj);

		ArrayList<ContentProviderOperation> insertOperations = new ArrayList<ContentProviderOperation>();

		// JSONArray jsons = obj.getJSONArray(ACCOUNT_UPLOAD_ID);
		JSONObject json = obj.getJSONObject("AccountUpload");

		// for (int i = 0; i < jsons.length(); i++) {
		// json = jsons.getJSONObject(i);
		insertOperations
				.add(ContentProviderOperation
						.newUpdate(WarrantiesTable.CONTENT_URI)
						.withSelection(WarrantiesTable.WARRANTY_ID + "=?", new String[] { account_upload_id })

						.withValue(WarrantiesTable.FILE_URL, json.getString(FILE_URL))
						.withValue(WarrantiesTable.PRODUCT_NAME_TO_UPLOAD, (json.isNull(PRODUCT_NAME)) ? "" : json.getString(PRODUCT_NAME))
						.withValue(WarrantiesTable.STORE_NAME, (json.isNull(STORE_NAME)) ? "" : json.getString(STORE_NAME))
						.withValue(
								WarrantiesTable.LIST_LABEL,
								((json.isNull(PRODUCT_NAME)) ? "" : json.getString(PRODUCT_NAME)) + " "
										+ ((json.isNull(STORE_NAME)) ? "" : json.getString(STORE_NAME)))
						.withValue(WarrantiesTable.PURCHASE_DATE,
								json.isNull(PURCHASE_DATE) ? null : DateUtis.parseDateToMillisecinds(json.getString(PURCHASE_DATE)))
						.withValue(WarrantiesTable.EXPIRATION_DATE, json.isNull(EXPIRATION_DATE) ? null : json.getString(EXPIRATION_DATE))
						.withValue(WarrantiesTable.FILE_NAME, json.getString(FILE_NAME))
						.withValue(WarrantiesTable.THUMBNAIL_URL, json.getString(THUMBNAIL_URL))
						.withValue(WarrantiesTable.CONTENT_TYPE_WARRANTY, json.getString(CONTENT_TYPE))
						.withValue(WarrantiesTable.COMMENTS, (json.isNull(COMMENTS)) ? "" : json.getString(COMMENTS)).build());
		// }

		// update existing values
		resolver.applyBatch(WarrantyHotelDBSchema.CONTENT_AUTHORITY, insertOperations);
	}

	/**
	 * Creation String such as "?,?,?,?,?,?"
	 */

	private String getPlaceHolder(String[] remains) {
		StringBuilder placeHolder = new StringBuilder();

		for (int i = 0; i < remains.length; i++) {
			placeHolder.append("?,");
		}
		// remove last comma
		placeHolder.setLength(placeHolder.length() - 1);

		return placeHolder.toString();
	}

	private String getPlaceHolder_v2(String[] remains) {
		StringBuilder sb = new StringBuilder();
		sb.append("(");
		final int len = remains.length;
		for (int i = 0; i < len; i++) {
			sb.append("'").append(remains[i]).append("',");
		}
		sb.setLength(sb.length() - 1);
		sb.append(")");
		return sb.toString();
	}
}
